package com.example.hrmsaas.system.controller;


import com.baomidou.mybatisplus.extension.api.R;
import com.example.hrmsaas.system.entity.Loginfo;
import com.example.hrmsaas.system.entity.Permission;
import com.example.hrmsaas.system.entity.Role;
import com.example.hrmsaas.system.entity.User;
import com.example.hrmsaas.system.service.ILoginfoService;
import com.example.hrmsaas.system.service.IPermissionService;
import com.example.hrmsaas.system.service.IUserService;
import com.example.hrmsaas.system.utils.*;
import com.example.hrmsaas.system.utils.DataUtils.ProfileResult;
import com.example.hrmsaas.system.utils.vo.PermissionVo;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.resource.spi.CommException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

@RestController
@RequestMapping("/login")
public class loginController {

    private Log log = (Log) LogFactory.getLog(loginController.class);

    @Autowired
    ILoginfoService loginfoService;

    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    IUserService userService;

    @Autowired
    IPermissionService permissionService;


    /***
     * 登录
     * @param username
     * @param password
     * @param session
     * @return
     */
    @RequestMapping("loginold")
    public ResultObject login(String username, String password, HttpSession session, HttpServletRequest request) {
        try {
            Subject subject = SecurityUtils.getSubject();//得到主体
            AuthenticationToken token = new UsernamePasswordToken(username, password);
            subject.login(token);
            ActiverUser activerUser = (ActiverUser) subject.getPrincipal();
            User user = activerUser.getUser();
            session.setAttribute("user", user);
            //TODO写入登录日志
            Loginfo loginfo = new Loginfo();
            loginfo.setLoginip(request.getRemoteAddr());
            loginfo.setLoginname(user.getName() + "-" + user.getUsername());
            loginfo.setLogintime(new Date());
            loginfoService.save(loginfo);
            //登陆成功
            return ResultObject.LOGIN_SUCCESS;
        } catch (Exception e) {
            //e.printStackTrace();
            log.error("用户名或密码错误");
            return ResultObject.LOGIN_ERROR;
        }
    }

    @RequestMapping("/jwttest")
    public DataGridView jwtTest() {
        CreateJwtTest jwtTest = new CreateJwtTest();
        String token = jwtTest.CreateJwt("88", "小白", "hrmsaas");
        return new DataGridView(token);
    }

    @RequestMapping(value = "/analysis", method = RequestMethod.GET)
    public DataGridView analysisToken(HttpServletRequest request) {
        String token = request.getParameter("token");
        CreateJwtTest jwtTest = new CreateJwtTest();
        Claims claims = jwtTest.analysis(token, "hrmsaas");
        log.info(claims);
        Map<String, Object> map = new HashMap<>();
        //解析常规内容
        map.put("id", claims.getId());
        map.put("str", claims.getSubject());
        map.put("salt", claims.getIssuedAt());

        //解析自定义内容
        map.put("CompanyId", claims.get("CompanyId"));
        map.put("CompanyName", claims.get("CompanyName"));
        return new DataGridView(map);

    }

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResultObject loginNew(@RequestBody Map<String, Object> param) {
        String mobile = (String) param.get("mobile");
        String password = (String) param.get("password");
        User user = loginfoService.getUserByMobile(mobile);
        //登录失败
        if (user == null) {
            return ResultObject.ISNULL_USER;
        } else {
            if(user.getPwd().equals(password)){
                Map<String, Object> map = new HashMap<>();
                map.put("companyId", user.getCompanyId());
                map.put("companyName", user.getCompanyName());
                //String salt = null != user.getSalt() ? user.getSalt() : "hrmsaas";
                String salt  = "hrmsaas";
                String token = jwtUtils.createJwt(user.getId(), user.getUsername(), salt, map);
                Map<String, Object> data = new HashMap<>();
                data.put("token", "Bearer "+token);
                return new ResultObject(200, data);
            }
            return ResultObject.USERPWD_ERROR;
        }
    }

    @RequestMapping(value = "/profile", method = RequestMethod.POST)
    public ResultObject getProfile(HttpServletRequest request) throws CommException {
        String token = request.getHeader("Authorization");
        if(StringUtils.isEmpty(token)){
            throw new CommException("用户未登录");
        }
        String Token = token.replace("Bearer","");
        //解析token,获取claims数据
        JwtUtils jwtUtils= new JwtUtils();
        Claims claims = jwtUtils.analysisJwt(Token,"hrmsaas");
        String userId = claims.getId();
        User user = userService.getUserByUid(userId);
        ProfileResult data = null;
        PermissionVo pMap = new PermissionVo();
        List<Permission> view = null;
        Map<String,Object> roles  = new HashMap<>();
        Set<String> menus = new HashSet<>();
        Set<String> points = new HashSet<>();
        Set<String> apis = new HashSet<>();
        switch(user.getLevel()){
            case "saasAdmin":
                pMap.setType(0);
                view =  permissionService.getPermissionAll(pMap);
                for (Permission perm : view) {
                    switch (perm.getType()) {
                        case 1:
                            menus.add(perm.getCode());
                            break;
                        case 2:
                            points.add(perm.getCode());
                            break;
                        case 3:
                            apis.add(perm.getCode());
                            break;
                    }
                    roles.put("menus",menus);
                    roles.put("points",points);
                    roles.put("apis",apis);
                }
                data = new ProfileResult(user.getMobile(),user.getUsername(),user.getCompanyName(),user.getCompanyId(),roles);
            break;

            case "coAdmin":
                pMap.setType(0);
                pMap.setEnVisible("1");
                view = permissionService.getPermissionAll(pMap);
                log.info(view);
                for (Permission perm : view) {
                    switch (perm.getType()) {
                        case 1:
                            menus.add(perm.getCode());
                            break;
                        case 2:
                            points.add(perm.getCode());
                            break;
                        case 3:
                            apis.add(perm.getCode());
                            break;
                    }
                    roles.put("menus",menus);
                    roles.put("points",points);
                    roles.put("apis",apis);
                }
                data = new ProfileResult(user.getMobile(),user.getUsername(),user.getCompanyName(),user.getCompanyId(),roles);

            break;

            default:
                Set<Role> roleData = userService.getRolesByUid(user.getId());
                for (Role role : roleData) {
                    Set<Permission> perms = role.getPermissions();
                    for (Permission perm : perms) {
                        switch (perm.getType()) {
                            case 1:
                                menus.add(perm.getCode());
                                break;
                            case 2:
                                points.add(perm.getCode());
                                break;
                            case 3:
                                apis.add(perm.getCode());
                                break;
                        }

                    }
                    roles.put("menus",menus);
                    roles.put("points",points);
                    roles.put("apis",apis);
                }
                data = new ProfileResult(user.getMobile(),user.getUsername(),user.getCompanyName(),user.getCompanyId(),roles);
            break;
        }
     return new ResultObject(200,data);
    }
}
